package com.qike.duola.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qike.duola.domain.*;
import com.qike.duola.dto.*;
import com.qike.duola.enums.StatusEnums;
import com.qike.duola.mapper.SysResourceMapper;
import com.qike.duola.mapper.SysRoleMapper;
import com.qike.duola.mapper.SysRoleResourceMapper;
import com.qike.duola.mapper.SysUserRoleMapper;
import com.qike.duola.service.IsysResourceService;
import com.qike.duola.service.IsysRoleService;
import com.qike.duola.utils.TimeTool;
import com.qike.duola.vo.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author: Eric.zhou
 * @Date: 2020/7/31 12:23
 */
@Service
public class SysRoleServiceImpl implements IsysRoleService {

    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysRoleResourceMapper sysRoleResourceMapper;
    @Autowired
    private IsysResourceService isysResourceService;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;


    /**
     * 角色列表
     *
     * @param resourceListDto
     * @return
     */
    @Override
    public RoleListVo roleList(ResourceListDto resourceListDto) {
        RoleListVo roleListVo = new RoleListVo();
        List<RoleVoList> list = new ArrayList<>();
        SysRoleExample example = new SysRoleExample();
        SysRoleExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(resourceListDto.getName())) {
            criteria.andNameLike(resourceListDto.getName());
        }
        criteria.andStatusEqualTo(Boolean.TRUE);
        example.setOrderByClause("create_at desc");
        Page page = PageHelper.startPage(resourceListDto.getStartPage(), resourceListDto.getPageSize());
        List<SysRole> sysRoles = sysRoleMapper.selectByExample(example);
        for (SysRole sysRole : sysRoles) {
            RoleVoList voList = new RoleVoList();
            voList.setId(sysRole.getId());
            voList.setCode(sysRole.getCode());
            voList.setCreateTime(TimeTool.dateFormat(sysRole.getCreateAt()));
            voList.setRemark(sysRole.getRemark());
            voList.setName(sysRole.getName());
            list.add(voList);
        }
        roleListVo.setList(list);
        roleListVo.setTotal(page.getTotal());
        return roleListVo;
    }

    /**
     * 删除角色
     *
     * @param roleDelDto
     */
    @Override
    public void roleDel(RoleDelDto roleDelDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        SysRole sysRole = new SysRole();
        sysRole.setStatus(Boolean.FALSE);
        sysRole.setId(roleDelDto.getId());
        sysRole.setUpdateAt(new Date());
        sysRole.setUpdateBy(userId);
        sysRoleMapper.updateByPrimaryKeySelective(sysRole);

    }

    /**
     * 添加角色
     *
     * @param roleCreateDto
     */
    @Override
    @Transactional
    public void roleCreate(RoleCreateDto roleCreateDto) {
        //创建角色
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        SysRole sysRole = new SysRole();
        sysRole.setStatus(Boolean.TRUE);
        sysRole.setCode(roleCreateDto.getCode());
        sysRole.setName(roleCreateDto.getName());
        sysRole.setRemark(roleCreateDto.getRemark());
        sysRole.setCreateBy(userId);
        sysRole.setCreateAt(new Date());
        sysRoleMapper.insertSelective(sysRole);
        //关联角色和资源
        for (Long resourceId : roleCreateDto.getResourceIds()) {
            SysRoleResource sysRoleResource = new SysRoleResource();
            sysRoleResource.setResourceId(resourceId);
            sysRoleResource.setRoleId(sysRole.getId());
            sysRoleResourceMapper.insertSelective(sysRoleResource);
        }


    }

    /**
     * 编辑角色
     *
     * @param roleEditDto
     */
    @Override
    @Transactional
    public void roleEdit(RoleEditDto roleEditDto) {
        //编辑角色
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        SysRole sysRole = new SysRole();
        sysRole.setId(roleEditDto.getId());
        sysRole.setCode(roleEditDto.getCode());
        sysRole.setName(roleEditDto.getName());
        sysRole.setRemark(roleEditDto.getRemark());
        sysRole.setUpdateBy(userId);
        sysRole.setUpdateAt(new Date());
        sysRoleMapper.updateByPrimaryKeySelective(sysRole);
        //关联角色和资源
        SysRoleResourceExample example = new SysRoleResourceExample();
        example.createCriteria().andRoleIdEqualTo(roleEditDto.getId());
        sysRoleResourceMapper.deleteByExample(example);
        for (Long resourceId : roleEditDto.getResourceIds()) {
            SysRoleResource sysRoleResource = new SysRoleResource();
            sysRoleResource.setResourceId(resourceId);
            sysRoleResource.setRoleId(sysRole.getId());
            sysRoleResourceMapper.insertSelective(sysRoleResource);
        }
    }

    /**
     * 角色详情
     *
     * @param roleInfoDto
     * @return
     */
    @Override
    public RoleInfoVo roleInfo(RoleInfoDto roleInfoDto) {
        RoleInfoVo vo = new RoleInfoVo();
        List<ResourceRoleInfoVo> list = new ArrayList<>();
        SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleInfoDto.getId());
        vo.setId(sysRole.getId());
        vo.setName(sysRole.getName());
        vo.setCode(sysRole.getCode());
        vo.setRemark(sysRole.getRemark());
        //todo 获取角色已有的菜单
        List<Long> haveIds = new ArrayList<>();
        List<MenuListVo> menuList = isysResourceService.getMenuListByRoleId(sysRole.getId());
        for (MenuListVo menuListVo : menuList) {
            haveIds.add(menuListVo.getId());
        }
        //todo 获取所有菜单
        ResourceListVo listVo = isysResourceService.resourceList(new ResourceListDto());

        List<ResourceVo> list1 = listVo.getList();
        //todo 比对两个菜单
        checkMenu(listVo.getList(), haveIds);
        vo.setList(list1);
        return vo;
    }

    /**
     * 通过用户id获取所有角色
     *
     * @param uid
     * @return
     */
    @Override
    public List<SysRole> getRoleByUid(Long uid) {
        SysUserRoleExample example = new SysUserRoleExample();
        example.createCriteria().andUserIdEqualTo(uid);
        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectByExample(example);
        List<Long> roleIds = new ArrayList<>();
        for (SysUserRole sysUserRole : sysUserRoles) {
            roleIds.add(sysUserRole.getRoleId());
        }
        if (roleIds.size()<=0){
            return null;
        }
        SysRoleExample roleExample = new SysRoleExample();
        roleExample.createCriteria().andIdIn(roleIds);
        List<SysRole> sysRoles = sysRoleMapper.selectByExample(roleExample);
        return sysRoles;
    }

    /**
     * 角色下拉列表
     *
     * @param name
     */
    @Override
    public List<RolePullListVo> rolePullList(String name) {
        List<RolePullListVo> vos = new ArrayList<>();
        SysRoleExample example = new SysRoleExample();
        SysRoleExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(name)){
            criteria.andNameLike(name);
        }
        criteria.andStatusEqualTo(Boolean.TRUE);
        List<SysRole> sysRoles = sysRoleMapper.selectByExample(example);
        for (SysRole sysRole : sysRoles) {
            RolePullListVo vo = new RolePullListVo();
            vo.setId(sysRole.getId());
            vo.setRoleName(sysRole.getName());
            vos.add(vo);
        }
        return vos;
    }


    /**
     * 在已有的权限上选中
     */
    private void checkMenu(List<ResourceVo> list, List<Long> haveIds) {
        for (ResourceVo resourceRoleInfoVo : list) {
            if (haveIds.contains(resourceRoleInfoVo.getId())){
                resourceRoleInfoVo.setCheck(true);
            }else {
                resourceRoleInfoVo.setCheck(false);
            }
            if (resourceRoleInfoVo.getChild().size() > 0) {
                this.checkMenu(resourceRoleInfoVo.getChild(), haveIds);
            }

        }

    }
}
